#include "sel.h"

#include "bt.h"
#include "edit.h"
#include "oled.h"
#include "ws2812.h"

#undef Handler
#define Handler Sel_HandleTypeDef*

#undef handler
#define handler (**(Sel_HandleTypeDef**)&handle)

void Sel_Init(void* handle, uint8_t idx) {
  Oled_ClearAll();
  Oled_ShowStringBig(0, 0, "     SELECT     ");

  handler.into = 0;
  handler.outo = 0;
  handler.mode = SEL_BEGIN;
  handler.save = 0;
  handler.x = handler.y = 0;
  handler.idx = idx;
  Sel_InitShow(handle);
  Sel_Reinit(handle);
}
void Sel_Reinit(void* handle) {
  Bt_Init(Sel_M_L, NULL, NULL, Sel_M_O,     // M
          Sel_U_L, Sel_U_W, NULL, Sel_U_O,  // U
          Sel_D_L, Sel_D_W, NULL, Sel_D_O,  // D
          Sel_L_L, Sel_L_W, NULL, Sel_L_O,  // L
          Sel_R_L, Sel_R_W, NULL, Sel_R_O,  // R
          150);
  handler.into = 0;
  Sel_ShowColor(handle);
  while (hbt.bu & BU_M) Bt_Update();
}

void Sel_InitShow(void* handle) {
  turn = 0xFF;
  Oled_ShowStringBig(0, 0, "     SELECT     ");
  turn = 0x00;
  Oled_ShowStringSmall(0, 2, "Coodinate: ");
  Oled_ShowStringSmall(86, 2, "(  ,  )");
  Oled_ShowNumSmall(92, 2, handler.x, 2);
  Oled_ShowNumSmall(110, 2, handler.y, 2);
  Oled_ShowStringSmall(0, 3, "Select mode:");
  Sel_ShowMode(handle);
  Oled_ShowStringSmall(0, 4, "Color:");
  Oled_ShowStringSmall(50, 4, "(   ,   ,   )");
  Sel_ShowColor(handle);
}
void Sel_ShowColor(void* handle) {
  Oled_ShowNumSmall(56, 4, hws.matrix.color[handler.x][handler.y][0], 3);
  Oled_ShowNumSmall(80, 4, hws.matrix.color[handler.x][handler.y][1], 3);
  Oled_ShowNumSmall(104, 4, hws.matrix.color[handler.x][handler.y][2], 3);
}
void Sel_ShowMode(void* handle) {
  char* str = handler.mode == SEL_POINT  ? "point"
              : handler.mode == SEL_LINE ? " line"
              : handler.mode == SEL_RECT ? " rect"
              : handler.mode == SEL_FILL ? " fill"
                                         : "error";
  Oled_ShowStringSmall(98, 3, str);
}
void Sel_Run(void* handle) {
  while (1) {
    Bt_Update();
    Bt_Run(handle);
    if (handler.into) {
      Edit_HandleTypeDef hedit;
      Edit_Init(&hedit, handler.x, handler.y, handler.mode);
      Edit_Run(&hedit);
      Sel_Reinit(handle);
      if (hedit.save) {
        Ws_Save(handler.idx);
      }
    }
    if (handler.outo) {
      return;
    }
  }
}

void Sel_M_L(void* handle) { handler.outo = 1; }
void Sel_M_O(void* handle) { handler.into = 1; }
void Sel_U_L(void* handle) {
  if (handler.y > 0)
    handler.y--;
  else
    handler.y = 7;
  Oled_ShowNumSmall(110, 2, handler.y, 2);
  Sel_ShowColor(handle);
}
void Sel_U_W(void* handle) {
  if ((hbt.bu & BU_C) == BU_C_U) {
    // 只有U键按下
    Sel_U_L(handle);
  } else if ((hbt.bu & BU_C) == (BU_C_U | BU_C_D)) {
    // 只有U和D键按下
    switch (handler.mode) {
      case SEL_POINT:
        handler.mode = SEL_RECT;
        break;
      case SEL_RECT:
        handler.mode = SEL_POINT;
        break;
      case SEL_LINE:
        handler.mode = SEL_FILL;
        break;
      case SEL_FILL:
        handler.mode = SEL_LINE;
        break;
    }
    Sel_ShowMode(handle);
    while (hbt.bu & BU_M) Bt_Update();
  }
}
void Sel_U_O(void* handle) {
  if ((hbt.bu & BU_C) != BU_C_U || hbt.hist) return;
  Sel_U_L(handle);
}

void Sel_D_L(void* handle) {
  if (handler.y < 7)
    handler.y++;
  else
    handler.y = 0;
  Oled_ShowNumSmall(110, 2, handler.y, 2);
  Sel_ShowColor(handle);
}
void Sel_D_W(void* handle) {
  if ((hbt.bu & BU_C) == BU_C_D) {
    // 只有D键按下
    Sel_D_L(handle);
  } else if ((hbt.bu & BU_C) == (BU_C_U | BU_C_D)) {
    // 只有U和D键按下
    switch (handler.mode) {
      case SEL_POINT:
        handler.mode = SEL_RECT;
        break;
      case SEL_RECT:
        handler.mode = SEL_POINT;
        break;
      case SEL_LINE:
        handler.mode = SEL_FILL;
        break;
      case SEL_FILL:
        handler.mode = SEL_LINE;
        break;
    }
    Sel_ShowMode(handle);
    while (hbt.bu & BU_M) Bt_Update();
  }
}
void Sel_D_O(void* handle) {
  if ((hbt.bu & BU_C) != BU_C_D || hbt.hist) return;
  Sel_D_L(handle);
}
void Sel_L_L(void* handle) {
  if (handler.x > 0)
    handler.x--;
  else
    handler.x = 31;
  Oled_ShowNumSmall(92, 2, handler.x, 2);
  Sel_ShowColor(handle);
}
void Sel_L_W(void* handle) {
  if ((hbt.bu & BU_C) == BU_C_L) {
    // 只有L键按下
    Sel_L_L(handle);
  } else if ((hbt.bu & BU_C) == (BU_C_L | BU_C_R)) {
    // 只有L和R键按下
    switch (handler.mode) {
      case SEL_POINT:
        handler.mode = SEL_LINE;
        break;
      case SEL_LINE:
        handler.mode = SEL_POINT;
        break;
      case SEL_RECT:
        handler.mode = SEL_FILL;
        break;
      case SEL_FILL:
        handler.mode = SEL_RECT;
        break;
    }
    Sel_ShowMode(handle);
    while (hbt.bu & BU_M) Bt_Update();
  }
}
void Sel_L_O(void* handle) {
  if ((hbt.bu & BU_C) != BU_C_L || hbt.hist) return;
  Sel_L_L(handle);
}

void Sel_R_L(void* handle) {
  if (handler.x < 31)
    handler.x++;
  else
    handler.x = 0;
  Oled_ShowNumSmall(92, 2, handler.x, 2);
  Sel_ShowColor(handle);
}
void Sel_R_W(void* handle) {
  if ((hbt.bu & BU_C) == BU_C_R) {
    // 只有R键按下
    Sel_R_L(handle);
  } else if ((hbt.bu & BU_C) == (BU_C_L | BU_C_R)) {
    // 只有L和R键按下
    switch (handler.mode) {
      case SEL_POINT:
        handler.mode = SEL_LINE;
        break;
      case SEL_LINE:
        handler.mode = SEL_POINT;
        break;
      case SEL_RECT:
        handler.mode = SEL_FILL;
        break;
      case SEL_FILL:
        handler.mode = SEL_RECT;
    }
    Sel_ShowMode(handle);
    while (hbt.bu & BU_M) Bt_Update();
  }
}
void Sel_R_O(void* handle) {
  if ((hbt.bu & BU_C) != BU_C_R || hbt.hist) return;
  Sel_R_L(handle);
}
